package com.tianchi.lexiang.deep;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.InputType;
import android.os.SystemClock;
import android.graphics.Bitmap;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.graphics.Rect;
import android.view.View.OnTouchListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.tianchi.lexiang.R;
import com.tianchi.lexiang.adapter.SongListViewAdapter;
import com.tianchi.lexiang.adapter.SongListViewAdapter.ChangePageDisplayCallBack;
import com.tianchi.lexiang.bean.HWRawData;
import com.tianchi.lexiang.bean.LeXiangConstants;
import com.tianchi.lexiang.bean.Song;
import com.tianchi.lexiang.constant.Commands;
import com.tianchi.lexiang.myinterface.IScreenService;
import com.tianchi.lexiang.myinterface.OnHanziFinishListener;
import com.tianchi.lexiang.myinterface.OnQueryCompleteListener;
import com.tianchi.lexiang.myinterface.impl.ServiceManager;
import com.tianchi.lexiang.myinterface.impl.SpellAndHanderWritePublic;
import com.tianchi.lexiang.service.GetAlreadyPointNums;
import com.tianchi.lexiang.service.JniService;
import com.tianchi.lexiang.util.AlreadyPointUtil;
import com.tianchi.lexiang.util.ScreenPostion;
import com.tianchi.lexiang.util.ScreenShot;
import com.tianchi.lexiang.util.DriftEffectUtil;
import com.tianchi.lexiang.util.ScreenPostionStateManager;
import com.tianchi.lexiang.util.ScreenPostionStateManager.Direction;
import com.tianchi.lexiang.util.SongInfoQuery;
import com.tianchi.lexiang.util.SongsClickRateUtil;
import com.tianchi.lexiang.view.ListViewWithPosition;
import com.tianchi.lexiang.view.PaintView;
import com.tianchi.lexiang.view.ScrollLayout;
import com.tianchi.lexiang.view.ScrollLayout.OnSnapOverLisener;

public class SongNameDisplayerScreen extends Activity implements
		OnTouchListener, OnClickListener, OnQueryCompleteListener, OnHanziFinishListener, ChangePageDisplayCallBack {

	private static final String TAG = "SongNameDisplayerScreen";
	private static final String SPELL = "spell";
	private static final String HANDER_WRITE = "handerWriter";

	private SongInfoQuery db = null;

	private String inputType = "spell";

	private final IScreenService screenService;

	private int currentPage = 1;
	private int currentTypeTotalPage = 1;
	private GestureDetector mGesture;

	/* ��д��ƴ���Ŀؼ� */
	private ImageView spellBtn;
	private ImageView handerWriteBtn;

	private ImageView spellBackDet;
	private ImageView spellEmpty;
	private ImageView handerWriteBackDet;
	private ImageView handerWriteEmpty;
	private ImageView handerWriteSure;
	private ImageView handerwritePerviousBtn;
	private ImageView handerwriteNextBtn;

	private String[] hanzisRecognize;
	private int hanzisLength;
	private int currentHandWritePage = 0;
	private int totalHandWritePage = 0;

	private EditText spellEdit;
	private EditText handerWriteEdit;

	private LinearLayout spellLayout;
	private LinearLayout handerWriteLayout;

	private HashMap<Integer, String> hashMap;
	private HashMap<String, Integer> phoneticLettersView;
	private String[] phoneticLetters;
	private List<String> designImages;

	private LinearLayout languageCategoryContainer;

	/* �������Ĳ˵��������Ӳ˵� */
	private LinearLayout wordsCategoryContainer;

	/* ҳ�����ʾ */
	private TextView pageRate;

	private String[] mLanguageCategories;
	private String mCurrentLanguageCategory;
	private String[] mWordsCategories;
	private String mCurrentWordsCategory;

	private String firstSpellOrSingerName = "";
	/* ��ʾ��һ�θ���չʾ��� �����ںͱ��ε�����бȽϣ����һ��ͱ�ʾ������ currentPage����Ϊ1 */
	private String lastLanguageCategory = "unknown";
	private String lastWordsCategory = "unkown";

	private ScrollLayout mScrollLayout;
	private List<Song> prePageContent;
	private List<Song> currentPageContent;
	private List<Song> nextPageContent;
	private ListViewWithPosition firstScreen;
	private ListViewWithPosition secondScreen;
	private ListViewWithPosition thirdScreen;
	private List<ListViewWithPosition> allScreen = new ArrayList<ListViewWithPosition>();

	private Direction direction = Direction.UNKNOWN;
	
	private String temporaryStr =""; 
	private String handerWriteStr ="";
	
	private Animation mScale;
	
	private AlreadyPointUtil alreadyPointUtil = AlreadyPointUtil.getInstance();
	private SongsClickRateUtil songsClickRate = SongsClickRateUtil.getInstence();
	private GetAlreadyPointNums numInstence = GetAlreadyPointNums.getInstence();
	
	private ScreenPostionStateManager screenContentManager = new ScreenPostionStateManager() {

		@Override
		public void refreshPreScreenContent(ListViewWithPosition list) {
			Log.d(TAG, "refreshPreScreenContent...currentPage==>" + currentPage);
			List<Song> prePageSongs = db.getPrePageContent(
					mCurrentLanguageCategory, mCurrentWordsCategory,
					firstSpellOrSingerName, currentPage, currentTypeTotalPage);
			final SongListViewAdapter preAdapter = (SongListViewAdapter) list
					.getAdapter();
			if(preAdapter != null){
				preAdapter.changeDataSource(prePageSongs);
			}
		}

		@Override
		public void refreshNextScreenContent(ListViewWithPosition list) {
			Log.d(TAG, "refreshNextScreenContent...currentPage=>" + currentPage);
			List<Song> nextPageSongs = db.getNextPageContent(
					mCurrentLanguageCategory, mCurrentWordsCategory,
					firstSpellOrSingerName, currentPage, currentTypeTotalPage);
			final SongListViewAdapter nextAdapter = (SongListViewAdapter) list
					.getAdapter();
			if(nextAdapter != null){	
				nextAdapter.changeDataSource(nextPageSongs);
			}
		}
	};

	private SpellAndHanderWritePublic instence = SpellAndHanderWritePublic
			.getInstence();

	private RecognizeHanziReceiver mReceiver = new RecognizeHanziReceiver();
	private PaintView mHandWrite;

	private long lastClickTime = 0;
	private boolean isCancel = false;
	
	private static final int UPDATE_HAND_WRITE = 4000;
	private static final int INIT_QUERY = 120000;
	private static final int INIT_QUERY_OVER = INIT_QUERY + 1;
	
	private static final int CURRENT_POSTION_QUERY = INIT_QUERY + 6;
	private static final int CURRENT_POSTION_QUERY_OVER = INIT_QUERY + 4;
	
	private static final int OTHER_POSITION_QUERY_OVER = INIT_QUERY + 5;
	private static final int OTHER_POSITION_QUERY = INIT_QUERY + 7;
	
	private static final int SPELL_POEITION_QUERY = INIT_QUERY + 8;
	
	private static final int SNAP_TO_SCREEN = INIT_QUERY + 9;
	
	private static final int SPELL_TO_SCREEN = INIT_QUERY + 10;
	
	
	private Thread mWorkerThread;
	
	private Handler queryHandler = new Handler(
			MyApplication.queryThread.getLooper()) {
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case INIT_QUERY:
				firstInitQuery();
				break;
			case CURRENT_POSTION_QUERY:
				startWorker();
				break;
			case OTHER_POSITION_QUERY:
				break;
			case SPELL_POEITION_QUERY:
				Log.d(TAG, "[queryHandler]....getMassage SPELL_POEITION_QUERY");
				checkSpell(spellEdit.getText().toString());
				break;
			default:
				break;
			}
		};
	};

	private void startWorker(){
		isCancel = false;
		mWorkerThread = new Thread("query worker"){
			public void run() {
				startQueryByTypeAndPage(mCurrentLanguageCategory,
						mCurrentWordsCategory, firstSpellOrSingerName,
						currentPage);
			};
		};
		mWorkerThread.start();
	}
	
	private void abortWorker() {
		if (mWorkerThread != null) {
            isCancel = true;
            try {
                mWorkerThread.join();
            } catch (InterruptedException ex) {
                Log.e(TAG, "join interrupted");
            }
            mWorkerThread = null;
        }
	}
	
	private Handler mainUIHandler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			switch (msg.what) {
			case UPDATE_HAND_WRITE:
				hanzisRecognize = (String[]) msg.obj;
				updateHanziShow();
				break;
			case INIT_QUERY_OVER:
				firstQueryOver();
				break;
			case CURRENT_POSTION_QUERY_OVER:
				refreshCurrentScreenContent();
				if (isCancel) {
					loge("[mainUIHandler]query has cancel");
					return ;
				}
				queryHandler.sendEmptyMessage(OTHER_POSITION_QUERY);
				break;
			case OTHER_POSITION_QUERY_OVER:
				refreshOtherScreenContent();
				break;
			case SNAP_TO_SCREEN:
				logd("[mainUIHandler] SNAP_TO_SCREEN ");
				mScrollLayout.snapToScreen(msg.arg1);
				break;
			case SPELL_TO_SCREEN:
				Log.d(TAG, "[mainUIHandler]  getMassage SPELL_TO_SCREEN_FALSE");
				setCurrentEnable();
				break;
			default:
				break;
			}
		};
	};

	private Handler updateHandwriteHandler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			hanzisRecognize = (String[]) msg.obj;
			hanzisLength = hanzisRecognize.length;
			totalHandWritePage = hanzisLength / 10;// 12 is the number we can
													// show one time
			if (hanzisLength % 10 != 0) {
				++totalHandWritePage;
			}
			currentHandWritePage = 0;
			updateHanziShow();
		};
	};

	private OnSnapOverLisener mySnapListen = new OnSnapOverLisener() {
		@Override
		public void snapRight() {
			previousPage();
		}

		@Override
		public void snapLeft() {
			nextPage();
		}
	};

	private void firstInitQuery() {
		if(db == null){
			db = SongInfoQuery.getSongInfoQueryWithContext(this);
		}
		currentTypeTotalPage = db.querySongsPageCountByType(
				mLanguageCategories[0], mWordsCategories[0],
				firstSpellOrSingerName);
		prePageContent = db.getPrePageContent(mLanguageCategories[0],
				mWordsCategories[0], firstSpellOrSingerName, currentPage,
				currentTypeTotalPage);
		currentPageContent = db.getCurrentpageContent(mLanguageCategories[0],
				mWordsCategories[0], firstSpellOrSingerName, currentPage,
				currentTypeTotalPage);
		nextPageContent = db.getNextPageContent(mLanguageCategories[0],
				mWordsCategories[0], firstSpellOrSingerName, currentPage,
				currentTypeTotalPage);
		mainUIHandler.sendEmptyMessage(INIT_QUERY_OVER);
	}

	private void refreshCurrentScreenContent() {
		for (ListViewWithPosition list : allScreen) {
			switch (list.getPosition()) {
			case CURRENT:
				Log.d(TAG, "grid " + list.getTag() + " refresh data source");
				((SongListViewAdapter) list.getAdapter())
						.changeDataSource(currentPageContent);
				break;
			default:
				break;
			}
		}
		updatePageRate(currentTypeTotalPage);
	}
	
	private void refreshOtherScreenContent() {
		for (ListViewWithPosition list : allScreen) {
			switch (list.getPosition()) {
			case PRE:
				Log.d(TAG, "grid " + list.getTag() + " refresh data source");
				((SongListViewAdapter) list.getAdapter())
						.changeDataSource(prePageContent);
				break;
			case NEXT:
				Log.d(TAG, "grid " + list.getTag() + " refresh data source");
				((SongListViewAdapter) list.getAdapter())
						.changeDataSource(nextPageContent);
			default:
				break;
				
			}
		}
		for (ListViewWithPosition list : allScreen) {
			if (list != null) {
				if (((SongListViewAdapter) list.getAdapter()) != null) {
					((SongListViewAdapter) list.getAdapter()).setPageDisplayListener(this);
				}
			}
		}
	}

	/**
	 * ���type����Ƿ�仯 ��ȷ���Ƿ�Ҫ��ѯ�µ���ҳ��
	 * 
	 * @param type
	 * @param page
	 * @param typeChange
	 */
	public void startQueryByTypeAndPage(String language, String word,
			String firstSpellOrSingerName, int page) {
		if (page == 1) {
			Log.d(TAG, "[startQueryByTypeAndPage] ..........");
			long startTime = System.currentTimeMillis();
			if (isCancel) {
				loge("[startQueryByTypeAndPage] will cancel getTotalCount");
				return ;
			}
			currentTypeTotalPage = db.querySongsPageCountByType(language, word,
					firstSpellOrSingerName);
			loge("[startQueryByTypeAndPage] get currentTypeTotalPage=" + currentHandWritePage
					+ ";;use time=>" + (System.currentTimeMillis() - startTime));
			if (isCancel) {
				loge("[startQueryByTypeAndPage]query has cancel");
				return ;
			}
			startTime = System.currentTimeMillis();
			
			currentPageContent = db.getCurrentpageContent(language, word,
					firstSpellOrSingerName, page, currentTypeTotalPage);
			loge("[startQueryByTypeAndPage]get currentPageContent use time=>" + (System.currentTimeMillis() - startTime));
			
			if (isCancel) {
				loge("[startQueryByTypeAndPage]query has cancel");
				return ;
			}
			mainUIHandler.sendEmptyMessage(CURRENT_POSTION_QUERY_OVER);
			
			logd("[startQueryByTypeAndPage] will start OTHER_POSITION_QUERY ");
			if (isCancel) {
				loge("[startQueryByTypeAndPage]query other screen has cancel");
				return ;
			}
			
			queryOtherScreenContent(mCurrentLanguageCategory,
					mCurrentWordsCategory, firstSpellOrSingerName,
					currentPage);
			
		} else {
			screenContentManager.runScreenPostionStateMachine(direction,
					allScreen);
		}
	}
	
	private void queryOtherScreenContent(String language, String word,
			String firstSpellOrSingerName, int page){
		long startTime = System.currentTimeMillis();
		prePageContent = db.getPrePageContent(language, word,
				firstSpellOrSingerName, page, currentTypeTotalPage);
		loge("[queryOtherScreenContent]get prePageContent use time=>" + (System.currentTimeMillis() - startTime));
		
		if (isCancel) {
			loge("[queryOtherScreenContent]query has cancel");
			return ;
		}
		
		startTime = System.currentTimeMillis();
		nextPageContent = db.getNextPageContent(language, word,
				firstSpellOrSingerName, page, currentTypeTotalPage);
		loge("[queryOtherScreenContent]get nextPageContent use time=>" + (System.currentTimeMillis() - startTime));
		
		if (isCancel) {
			loge("[queryOtherScreenContent]query has cancel");
			return ;
		}
		mainUIHandler.sendEmptyMessage(OTHER_POSITION_QUERY_OVER);
	}

	public SongNameDisplayerScreen() {
		this.screenService = ServiceManager.getScreenService();
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		logd("[onCreate]...........");
		setContentView(R.layout.title_song_gridview);
		db = SongInfoQuery.getSongInfoQueryWithContext(this);
		initView();
		initLanguageMenuContent();
		initWordsMenuContent();
		mGesture = new GestureDetector(this, new MyGestureDetector());
	}

	/* ��ʼ�� */
	private void initView() {
		LinearLayout mLeftLinear = (LinearLayout) findViewById(R.id.left);
		mScrollLayout = (ScrollLayout) findViewById(R.id.scrollLayout);
		mScrollLayout.setSnapListerner(mySnapListen);

		firstScreen = createViewWithTag(LeXiangConstants.PRE_SCREEN_TAG);
		firstScreen.setPosition(ScreenPostion.PRE);
		allScreen.add(firstScreen);

		secondScreen = createViewWithTag(LeXiangConstants.CURRENT_SCREEN_TAG);
		secondScreen.setPosition(ScreenPostion.CURRENT);
		allScreen.add(secondScreen);

		thirdScreen = createViewWithTag(LeXiangConstants.NEXT_SCREEN_TAG);
		thirdScreen.setPosition(ScreenPostion.NEXT);
		allScreen.add(thirdScreen);

		mScrollLayout.addView(firstScreen);
		mScrollLayout.addView(secondScreen);
		mScrollLayout.addView(thirdScreen);

		/* ��ʼ�����Բ˵� */
		languageCategoryContainer = (LinearLayout) mLeftLinear
				.findViewById(R.id.language_menu_container);
		int languageChildCount = languageCategoryContainer.getChildCount();
		for (int i = 0; i < languageChildCount; i++) {
			languageCategoryContainer.getChildAt(i).setOnClickListener(this);
		}

		/* ���»�����˵� */
		wordsCategoryContainer = (LinearLayout) mLeftLinear
				.findViewById(R.id.words_menu_container);
		int wordsChildCount = wordsCategoryContainer.getChildCount();
		for (int i = 0; i < wordsChildCount; i++) {
			wordsCategoryContainer.getChildAt(i).setOnClickListener(this);
		}

		/* ҳ����ʾ��ĳ�ʼ�� */
		pageRate = (TextView) findViewById(R.id.page_rate);

		/* ��д��ƴ���ؼ��ĳ�ʼ�� */
		spellBtn = (ImageView) findViewById(R.id.spell_btn);
		spellBtn.setOnClickListener(new SpellAndHanderWrite());

		handerWriteBtn = (ImageView) findViewById(R.id.hand_write_btn);
		handerWriteBtn.setOnClickListener(new SpellAndHanderWrite());

		/* ƴ����ɾ��ť�ļ����¼� */
		spellBackDet = (ImageView) findViewById(R.id.spell_back_delete_view);
		spellBackDet.setOnClickListener(this);

		/* ƴ����հ�ť�ļ����¼� */
		spellEmpty = (ImageView) findViewById(R.id.spell_empty_view);
		spellEmpty.setOnClickListener(this);
		
		mScale = AnimationUtils.loadAnimation(this, R.anim.scale);
		phoneticLettersView = instence.getPhoneticLettersView(this);
		phoneticLetters = instence.getAllPhoneticLetters(this);

		/* ȡ��ƴ����ĸ�İ�ť��Ӧ��ID */
		hashMap = instence.BuliderSpellAdapter(this);
		Set<Integer> viewIdSet = hashMap.keySet();
		Iterator<Integer> mIterator = viewIdSet.iterator();
		while (mIterator.hasNext()) {
			findViewById(mIterator.next()).setOnClickListener(this);
			
		}

		/* ��д��ɾ��ť�ļ��� */
		handerWriteBackDet = (ImageView) findViewById(R.id.hander_write_back_delete_view);
		handerWriteBackDet.setOnClickListener(new handerWriteClick());
		

		/* ��д��հ�ť�ļ��� */
		handerWriteEmpty = (ImageView) findViewById(R.id.hander_write_empty);
		handerWriteEmpty.setOnClickListener(new handerWriteClick());
		
		/* ��дȷ����ť�ļ��� */
		handerWriteSure =(ImageView)findViewById(R.id.hander_write_sure);
		handerWriteSure.setOnClickListener(this);
		
		/* ѡ����д�ֵļ��� */
		for (int i = 0; i < instence.showTxtId.length; i++) {
			findViewById(instence.showTxtId[i]).setOnClickListener(new handerWriteClick());
		}

		spellLayout = (LinearLayout) findViewById(R.id.spell_layout);
		handerWriteLayout = (LinearLayout) findViewById(R.id.hander_write_layout);

		spellEdit = (EditText) findViewById(R.id.spell_edit);
		spellEdit.setInputType(InputType.TYPE_NULL);
		spellEdit.setLongClickable(false);

		handerWriteEdit = (EditText) findViewById(R.id.hander_write_edit);
		handerWriteEdit.setInputType(InputType.TYPE_NULL);
		handerWriteEdit.setLongClickable(false);

		mHandWrite = (PaintView) findViewById(R.id.paintView);
		mHandWrite.setHanziFinishListener(this);

		handerwritePerviousBtn = (ImageView) findViewById(R.id.handerwrite_previous_btn);
		handerwritePerviousBtn.setOnClickListener(this);
		handerwriteNextBtn = (ImageView) findViewById(R.id.handerwrite_next_btn);
		handerwriteNextBtn.setOnClickListener(this);
	}

	@Override
	protected void onResume() {
		super.onResume();
		logd("[onResume()].................");
		IntentFilter mFileFilter = new IntentFilter(
				LeXiangConstants.RECOGNIZE_HANZI_ACTION);
		registerReceiver(mReceiver, mFileFilter);
	}

	private void firstQueryOver() {
		final SongListViewAdapter firstAdapter = new SongListViewAdapter(this,
				prePageContent);
		firstScreen.setAdapter(firstAdapter);
		firstAdapter.setPageDisplayListener(this);

		final SongListViewAdapter secondAdapter = new SongListViewAdapter(this,
				currentPageContent);
		secondScreen.setAdapter(secondAdapter);
		secondAdapter.setPageDisplayListener(this);

		final SongListViewAdapter thirdAdapter = new SongListViewAdapter(this,
				nextPageContent);
		thirdScreen.setAdapter(thirdAdapter);
		thirdAdapter.setPageDisplayListener(this);

		if (currentTypeTotalPage == 0) {
			pageRate.setText("0/" + currentTypeTotalPage);
		} else {
			pageRate.setText("1/" + currentTypeTotalPage);
		}
	}

	private ListViewWithPosition createViewWithTag(String tag) {
		ListViewWithPosition mListView = (ListViewWithPosition) LayoutInflater
				.from(this).inflate(R.xml.song_list_xml, null);
		mListView.setTag(tag);
//		mListView.setOnItemClickListener(this);
		mListView.setOnTouchListener(this);
		return mListView;
	}

	@Override
	protected void onStart() {
		super.onStart();
		logd("[onStrat]............");
		queryHandler.sendEmptyMessage(INIT_QUERY);
		queryHandler.sendEmptyMessage(SPELL_POEITION_QUERY);
	}

	/**
	 * ����ҳ��ť���¼�����
	 * 
	 * @param v
	 */
	public void pageControlHandler(View v) {
		logd("this is pageControlHandler()");
		mainUIHandler.removeMessages(SNAP_TO_SCREEN);
		Message msg = mainUIHandler.obtainMessage(SNAP_TO_SCREEN);
		switch (v.getId()) {
		case R.id.previous_page:
			previousPage();
			msg.arg1 = 0;
			break;
		case R.id.next_page:
			nextPage();
			msg.arg1 = 2;
			break;
		default:
			Log.d(TAG, "here is pageControlHandler() ,unknown v =>" + v);
			break;
		}
		mainUIHandler.sendMessageDelayed(msg, 500);
	}

	private void updatePageRate(int totalCount) {
		String pageRateContent = currentPage + "/" + totalCount;
		pageRate.setText(pageRateContent);
	}

	/**
	 * go back
	 * 
	 * @param v
	 */
	public void onGoBackClick(View v) {
		clreanScreen();
		pageRate.setText("");
		screenService.goBack();
	}

	/**
	 * ������Բ˵�
	 */
	private void initLanguageMenuContent() {
		mLanguageCategories = getSingerCategories(R.array.language_category);
		int childCout = languageCategoryContainer.getChildCount();
		View child = null;
		for (int i = 0; i < childCout; i++) {
			child = languageCategoryContainer.getChildAt(i);
			if (child == null) {
				loge("get child from singerCategoryContainer cause error");
				return;
			} else {
				((TextView) child).setText(mLanguageCategories[i]);
			}
		}
		languageCategoryContainer.getChildAt(0).setBackgroundResource(
				R.drawable.title_arrow_down);
		mCurrentLanguageCategory = mLanguageCategories[0];
	}

	/**
	 * �������˵�
	 */
	private void initWordsMenuContent() {
		mWordsCategories = getSingerCategories(R.array.words_category);
		int childCout = wordsCategoryContainer.getChildCount();
		View child = null;
		for (int i = 0; i < childCout; i++) {
			child = wordsCategoryContainer.getChildAt(i);
			if (child == null) {
				loge("get child from singerCategoryContainer cause error");
				return;
			} else {
				((TextView) child).setText(mWordsCategories[i]);
			}
		}
		wordsCategoryContainer.getChildAt(0).setBackgroundResource(
				R.drawable.title_arrow_down);
		mCurrentWordsCategory = mWordsCategories[0];
	}

	private String[] getSingerCategories(int resourceId) {
		Resources mResources = getResources();
		return mResources.getStringArray(resourceId);
	}

	@Override
	public boolean onTouch(View v, MotionEvent event) {
		return mGesture.onTouchEvent(event);

	}

	@Override
	public void onClick(View v) {
		View languageChild = null;
		View wordsChild = null;
		int childLanguageCout = languageCategoryContainer.getChildCount();
		int childWordsCout = wordsCategoryContainer.getChildCount();
		if (v.getParent() == languageCategoryContainer) {
			for (int i = 0; i < childLanguageCout; i++) {
				languageChild = languageCategoryContainer.getChildAt(i);
				if (languageChild == null) {
					loge("get child from languageCategoryContainer cause error");
					return;
				} else if (languageChild != null && languageChild != v) {
					languageChild.setBackgroundResource(0);// �Ƴ��ͷ����
				} else if (languageChild == v) {
					languageChild.setBackgroundResource(R.drawable.title_arrow_down);
					mCurrentLanguageCategory = mLanguageCategories[i];
					/* �˴��ж����Ը�û�ı� */
					if (!lastLanguageCategory.equals(mCurrentLanguageCategory)) {
						lastLanguageCategory = mCurrentLanguageCategory;
						currentPage = 1;
					} else {
						// �˴���ʾ��������ϴ���� ҳ�����
						logd("this is the same type");
					}
				}
			}
		} else if (v.getParent() == wordsCategoryContainer) {
			for (int i = 0; i < childWordsCout; i++) {
				wordsChild = wordsCategoryContainer.getChildAt(i);
				if (wordsChild == null) {
					loge("get child from wordsCategoryContainer cause error");
					return;
				} else if (wordsChild != null && wordsChild != v) {
					wordsChild.setBackgroundResource(0);// �Ƴ��ͷ����
				} else if (wordsChild == v) {
					wordsChild.setBackgroundResource(R.drawable.title_arrow_down);
					mCurrentWordsCategory = mWordsCategories[i];
					/* �˴��ж�������û�иı� */
					if (!lastWordsCategory.equals(mCurrentWordsCategory)) {
						lastWordsCategory = mCurrentWordsCategory;
						currentPage = 1;
					} else {
						// �˴���ʾ��������ϴ���� ҳ�����
						logd("this is the same type");
					}
				}
			}
		}
		int id = v.getId();
		/* ƴ������ĸ��ť */
		String content = hashMap.get(id);
		if (content != null) {
			findViewById(id).startAnimation(mScale);
			spellEdit.append(content);
			Log.d(TAG, "[onCLick]....setMessage SPELL_POEITION_QUERY");
			if(designImages != null){
				designImages = null;
			}
//			queryHandler.sendEmptyMessage(SPELL_POEITION_QUERY);
		}

		switch (id) {
		/* ƴ����ɾ��ť */
		case R.id.spell_back_delete_view:
			spellBackDet.startAnimation(mScale);
			String temp = spellEdit.getText().toString();
			if(designImages != null){
				designImages = null;
			}
			if (temp != null && !"".equals(temp)) {
				temp = temp.substring(0, temp.length() - 1);
				spellEdit.setText(temp);
			} else {
				spellEdit.setText("");
			}
//			queryHandler.sendEmptyMessage(SPELL_POEITION_QUERY);
			
			break;
		/* ƴ����հ�ť */
		case R.id.spell_empty_view:
			spellEmpty.startAnimation(mScale);
			if(designImages != null){
				designImages = null;
			}
			spellEdit.setText("");
			break;
			
		case R.id.hander_write_sure:
				
			break;

		case R.id.handerwrite_previous_btn:
			--currentHandWritePage;
			if (currentHandWritePage <= 0) {
				currentHandWritePage = 0;
			}
			updateHanziShow();
			break;

		case R.id.handerwrite_next_btn:
			++currentHandWritePage;
			if (currentHandWritePage >= totalHandWritePage) {
				currentHandWritePage = totalHandWritePage - 1;
			}
			updateHanziShow();
			break;
		}
		if (SPELL.equals(inputType)) {
			currentPage = 1;
			firstSpellOrSingerName = spellEdit.getText().toString();
		} else if (HANDER_WRITE.equals(inputType)) {
			currentPage = 1;
			firstSpellOrSingerName = handerWriteEdit.getText().toString();
		}
		
		long currentTime = System.currentTimeMillis();
		long period = currentTime - lastClickTime;
		if (period < 2000) {
			logd("[onClick] click fast , cancel last query , exec the new query");
			abortWorker();
		}
		lastClickTime = currentTime;
		clreanScreen();
		queryHandler.sendEmptyMessage(CURRENT_POSTION_QUERY);
		if(id == R.id.spell_empty_view || content != null || id == R.id.spell_back_delete_view){
			clreanLanguageAndWords();
			queryHandler.sendEmptyMessage(SPELL_POEITION_QUERY);
		}
	}
	
	private void checkSpell(String spellStr){
		Log.d(TAG, "[checkSpell].....checkSpell is not has");
		for(int i = 0 ;i < phoneticLetters.length; i++){
			String spellStrs = spellStr + phoneticLetters[i];
			String currentSpell =  phoneticLetters[i];
			boolean bool = db.judgmentFirstSpell(spellStrs);
			Log.d(TAG, "[checkSpell]....bool====>" + bool);
			if(!bool){
				if(designImages == null){
					designImages = new ArrayList<String>();
				}
				designImages.add(currentSpell);
			}
		}
		mainUIHandler.sendEmptyMessage(SPELL_TO_SCREEN);
	}
	
	private void setCurrentEnable(){
		Log.d(TAG, "[setCurrentEnable]...start");
		setAllSpellViewEable();
		if(designImages != null){
			for(int i= 0; i< designImages.size(); i++){
				ImageView currentSpellView = (ImageView)findViewById(phoneticLettersView.get(designImages.get(i)));
				currentSpellView.setAlpha(100);
				currentSpellView.setEnabled(false);
			}
		}
	}
	
	private void setAllSpellViewEable(){
		for(int i = 0 ;i < phoneticLetters.length; i++){
			ImageView allSpellImageView = (ImageView)findViewById(phoneticLettersView.get(phoneticLetters[i]));
			allSpellImageView.setAlpha(255);
			allSpellImageView.setEnabled(true);
		}
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		if (mGesture.onTouchEvent(event)) {
			return true;
		}
		return super.onTouchEvent(event);
	}

	/**
	 * ��Ļ�Ļ�������
	 * 
	 * @author aa
	 * 
	 */
	private class MyGestureDetector extends SimpleOnGestureListener {
//		private static final int SWIPE_MIN_DISTANCE = 120;
//		private static final int SWIPE_THRESHOLD_VELOCITY = 200;

		@Override
		public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
				float velocityY) {
//			if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE
//					&& Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
//				previousPage();
//			} else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE
//					&& Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
//				nextPage();
//			}
			return super.onFling(e1, e2, velocityX, velocityY);
		}
	}

	/**
	 * ��ѯ��һҳ
	 */
	public void previousPage() {
		Log.d(TAG, "previousPage()");
		direction = Direction.RIGHT;
		if (currentPage > 1) {
			currentPage--;
		} else {
			currentPage = currentTypeTotalPage;
		}
		updatePageRate(currentTypeTotalPage);
		screenContentManager.runScreenPostionStateMachine(direction, allScreen);
	}

	/**
	 * ��ѯ��һҳ
	 */
	public void nextPage() {
		Log.d(TAG, "nextPage()");
		direction = Direction.LEFT;
		currentPage++;
		if (currentPage > currentTypeTotalPage) {
			Log.d(TAG, "currentPage =>" + currentPage + " is the end of page ,currentTypeTotalPage=" + currentTypeTotalPage);
			currentPage = 1;
		}
		updatePageRate(currentTypeTotalPage);
		screenContentManager.runScreenPostionStateMachine(direction, allScreen);
	}

	@Override
	protected void onPause() {
		super.onPause();
		logd("[onPause]..................");
		unregisterReceiver(mReceiver);
	}

	private void loge(String msg) {
		Log.e(TAG, msg);
	}

	private void logd(String msg) {
		Log.d(TAG, msg);
	}

	@Override
	public void onQueryComplete(int totalCount) {
		currentTypeTotalPage = totalCount;
		logd("[onQueryComplete]" + Thread.currentThread().getName());
		updatePageRate(totalCount);
	}

	private class SpellAndHanderWrite implements OnClickListener {

		@Override
		public void onClick(View v) {
			int id = v.getId();
			switch (id) {
			case R.id.spell_btn:
				inputType = SPELL;
				spellLayout.setVisibility(View.VISIBLE);
				handerWriteLayout.setVisibility(View.GONE);
				handerWriteEdit.setText("");
				firstSpellOrSingerName = "";
				if(designImages != null){
					designImages = null;
					queryHandler.sendEmptyMessage(SPELL_POEITION_QUERY);
				}
				break;
			case R.id.hand_write_btn:
				inputType = HANDER_WRITE;
				spellLayout.setVisibility(View.GONE);
				handerWriteLayout.setVisibility(View.VISIBLE);
				spellEdit.setText("");
				firstSpellOrSingerName = "";
				break;

			default:
				break;
			}

		}
	}
	
	private void songControl(final Song song, TextView view) {
		driftAnimation(view);
		queryHandler.postDelayed(new Runnable() {
			@Override
			public void run() {
				alreadyPointUtil.insertAlreadyPointSong(LeXiangConstants.DEMAND, song.id, song.songName);
				mainUIHandler.post(new Runnable() {
					public void run() {
						doItemClickWork(song);
					}
				});
			}
		}, 800);
	}

	
	private void doItemClickWork(final Song song){
		Log.d(TAG, "[SongNameDisplayerScreen]...onItemClick===>song.songName" + song.songName);
		queryHandler.post(new Runnable() {
			@Override
			public void run() {
				numInstence.sendBroadcastUpdateAlreadyPointNumber(SongNameDisplayerScreen.this);
				numInstence.sendBroadcastUpdateOsdSubTitle(SongNameDisplayerScreen.this);
				numInstence.sendBroadcastPendingToSyncServerAlreadyPoint(SongNameDisplayerScreen.this, song.id, song.songName, -1, Commands.CMD_DB_ADD);
				songsClickRate.setSongsClickRate(song.id);
			}	
		});
		clrean();
	}
	
	private void clrean(){
		spellEdit.setText("");
		handerWriteEdit.setText("");
		if(designImages != null){
			designImages = null;
			queryHandler.sendEmptyMessage(SPELL_POEITION_QUERY);
		}
		clreanLanguageAndWords();
	}

	private void driftAnimation(View view){
		log("[driftAnimation]");
		long startTime = SystemClock.currentThreadTimeMillis();
		final Rect captureRect = getRectOfView(view);
		final int[] startPos = getPosOfView(view);
		log("[driftAnimation]startPos=>" + startPos[0] + "," + startPos[1]);
		captureRect.left = startPos[0];
		captureRect.top = startPos[1] - 50 ;
		captureRect.bottom = captureRect.top + view.getHeight();
		log("[driftAnimation]modify captureRect =>" + captureRect);
		Bitmap srcBitmap = ScreenShot.shootByRect(
				SongNameDisplayerScreen.this, captureRect);

		log("[driftAnimation] create capture bitmap use time=>" + (SystemClock.currentThreadTimeMillis() - startTime));
		final int fromX = startPos[0];
		final int fromY = startPos[1];

		final int[] desPos = Home.getDesPos();
		final int toX = desPos[0];
		final int toY = desPos[1];

		log("fromX--toX=>" + fromX + "-" + toX);
		log("fromY--toY=>" + fromY + "-" + toY);
		DriftEffectUtil.getInstance().drift(SongNameDisplayerScreen.this,
				srcBitmap, fromX, fromY, 1200, 980);	
	}
	
	private Rect getRectOfView(View v) {
		return DriftEffectUtil.getInstance().getRectOfView(v);
	}

	private int[] getPosOfView(View v){
		return DriftEffectUtil.getInstance().getPosOfView(v);
	}

	private void clreanLanguageAndWords(){
		int languageChildCout = languageCategoryContainer.getChildCount();
		for(int i=0; i<languageChildCout; i++){
			if(lastLanguageCategory.equals(mLanguageCategories[i])){
				View languageChild = languageCategoryContainer.getChildAt(i);
				languageChild.setBackgroundResource(0);
			}
		}
		
		int wordChildCout = wordsCategoryContainer.getChildCount();
		for(int i=0; i<wordChildCout; i++){
			if(lastWordsCategory.equals(mWordsCategories[i])){
				View wordChild = wordsCategoryContainer.getChildAt(i);
				wordChild.setBackgroundResource(0);
			}
		}
		languageCategoryContainer.getChildAt(0).setBackgroundResource(R.drawable.title_arrow_down);
		wordsCategoryContainer.getChildAt(0).setBackgroundResource(R.drawable.title_arrow_down);
		mCurrentLanguageCategory = mLanguageCategories[0];
		mCurrentWordsCategory = mWordsCategories[0];
		
	}

	private void updateHanziShow() {
		Log.d(TAG, "[updateHanziShow]...........");
		for (int i = 0; i < 10; i++) {
			((TextView) findViewById(instence.showTxtId[i])).setText("");
		}
		int min = Math.min(10, hanzisLength - 10 * currentHandWritePage);
		for (int i = 0; i < min; i++) {
			int position = i + currentHandWritePage * 10;
			String tmp = String.valueOf(hanzisRecognize[position]);
			try {
				String des = new String(tmp.getBytes("utf-8"), "utf-8");
				((TextView) findViewById(instence.showTxtId[i])).setText(des);
				if(position == 0){
					temporaryStr = des;
				}
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
		}
		Log.d(TAG, "[updateHanziShow]=====temporaryStr====>" + temporaryStr);
		handerWriteStr += temporaryStr;
		Log.d(TAG, "[updateHanziShow]=====handerWriteStr====>" + handerWriteStr);
		handerWriteEdit.setText(handerWriteStr);
	}

	@Override
	public void onOneHanziFinish(HWRawData rawData) {
		Intent service = new Intent(this,JniService.class);
		service.putExtra(JniService.CMD, JniService.GET_RECOGNISE);
		Log.d(TAG, "[onOneHanziFinish] will recognise hanzi by HWRawData");
		service.putExtra("raw_data", rawData);
		startService(service);
	}

	class RecognizeHanziReceiver extends BroadcastReceiver {
		@Override
		public void onReceive(Context context, Intent intent) {
			String[] hanzis = intent.getStringArrayExtra(LeXiangConstants.RECOGNIZE_HANZI);
			Message msg = updateHandwriteHandler.obtainMessage();
			msg.obj = hanzis;
			updateHandwriteHandler.sendMessage(msg);
		}
	}
	
	@Override 
	public boolean onKeyDown(int keyCode, KeyEvent event) { 
		if(keyCode == KeyEvent.KEYCODE_BACK) { 
			Log.d(TAG,"[onKeyDown]this is back event ,ingore it");
			return true; 
		} else if(keyCode == KeyEvent.KEYCODE_MENU) {
			return true; 
		}     
		return super.onKeyDown(keyCode, event); 
	}
	
	private void clreanScreen(){
		for (ListViewWithPosition list : allScreen) {
			if (list != null) {
				if (((SongListViewAdapter) list.getAdapter()) != null) {
					((SongListViewAdapter) list.getAdapter())
							.changeDataSource(new ArrayList<Song>());
				}
			}
		}
	}

	@Override
	public void onOneHanziFinish(char[] results) {
		hanzisRecognize = new String[results.length];
		hanzisLength = hanzisRecognize.length;
		for (int i = 0; i < hanzisLength; i++) {
			hanzisRecognize[i] = String.valueOf(results[i]);
			Log.d(TAG,"[onOneHanziFinish]hanziArr["+i+"]==>"+hanzisRecognize[i]);
		}
		totalHandWritePage = hanzisLength / 10;// 12 is the number we can
												// show one time
		if (hanzisLength % 10 != 0) {
			++totalHandWritePage;
		}
		currentHandWritePage = 0;
		runOnUiThread(new Runnable() {
			public void run() {
				updateHanziShow();
			}
		});
	}
	
	class handerWriteClick implements OnClickListener{
	
		@Override
		public void onClick(View view) {
			int id = view.getId();
			for (int i = 0; i < instence.showTxtId.length; i++) {
				if (id == instence.showTxtId[i]) {
					temporaryStr = ((TextView) findViewById(id)).getText().toString();
				}
				Log.d(TAG, "[handerWriteClick]....temporaryStr====>" + temporaryStr);
				if(handerWriteStr != null && !"".equals(handerWriteStr)){
					 handerWriteStr = handerWriteStr.substring(0, handerWriteStr.length() - 1) + temporaryStr;
				}
				Log.d(TAG, "[handerWriteClick]....handerWriteStr====>" + handerWriteStr);
			}
			switch (id) {
			case R.id.hander_write_back_delete_view:
				if (handerWriteStr != null && !"".equals(handerWriteStr)) {
					handerWriteStr = handerWriteStr.substring(0, handerWriteStr.length() - 1);
				} else {
					handerWriteStr = "";
				}
				for (int i = 0; i < 10; i++) {
					((TextView) findViewById(instence.showTxtId[i])).setText("");
				}
				Log.d(TAG, "[handerWriteClick]....delete...handerWriteStr====>" + handerWriteStr);
				break;
			case R.id.hander_write_empty:
				handerWriteStr = "";
				Log.d(TAG, "[handerWriteClick]....empty...handerWriteStr====>" + handerWriteStr);
				for (int i = 0; i < 10; i++) {
					((TextView) findViewById(instence.showTxtId[i])).setText("");
				}
				break;

			default:
				break;
			}
			handerWriteEdit.setText(handerWriteStr);
		}
		
	}
	
	private void log(String msg){
		Log.d(TAG, msg);
	}

	@Override
	public void remoteMusic(Song song, TextView view) {
		songControl(song, view);
	}

	@Override
	public void clearScreen() {
		clrean();
	}

	@Override
	public void pageDisplay(Song song) {
		doItemClickWork(song);
	}
	
}
